<script lang="ts" setup>
  import { reactive, ref, unref, computed, onMounted } from 'vue';
  import { PlusOutlined } from '@ant-design/icons-vue';
  import { btnPerEnums } from '/@/enums/btnEnum';
  import { getAppList, deleteApp } from '/@/api/app';
  import { useMessage } from '/@/hooks/web/useMessage';
  import AppModal from './AddAppModal.vue';
  import { AUTH_TYPE_LIST, SYNC_SF_TYPE } from './const.js';
  import { useUserStore } from '/@/store/modules/user';
  import { useMultipleTabStore } from '/@/store/modules/multipleTab';
  import { Icon } from '/@/components/Icon';

  const tabStore = useMultipleTabStore();
  const userStore = useUserStore();
  const currentId = computed(() => userStore.getLoginApp?.currentId || '');
  const { createMessage } = useMessage();

  const currentUserId = computed(() => userStore.getUserInfo?.userId || null);

  onMounted(() => {
    // debugger;
    if (currentUserId.value == null) {
      window.location.reload();
    }
  });

  const state = reactive({
    loading: false,
  });
  const searchFormRef = ref();
  const searchForm = reactive({
    appName: '',
    appId: '',
    createBy: '',
  });
  const searchFormActions = {
    resetFields(formEl) {
      formEl.resetFields();
      this.search();
    },
    search() {
      pgActions.resetPg();
      searchFormActions.onSearch();
    },
    onSearch: async function () {
      let params = {
        startIndex: pg.current,
        pageSize: pg.size,
        clientName: searchForm.appName,
        createBy: searchForm.createBy,
      };
      state.loading = true;
      let { data, respCode } = await getAppList(params);
      state.loading = false;
      data.data = [];
      if (respCode === 200) {
        table.data = data.list;
        pg.total = data.total;
      }
    },
  };

  const table = reactive({
    data: [],
    selected: [] as any,
    detailsData: null as any,
    detailsVisible: false,
  });

  const tableActions = {
    selectionChange(v) {
      table.selected = v;
    },
    details(r) {
      d_modal.data = r;
      d_modal.visible = true;
    },
    create() {
      modal.data = undefined;
      modalActions.show();
    },
    update(r) {
      modal.data = r;
      modalActions.show();
    },
    delete(r) {
      deleteAppReq([r.id]);
    },
    batchDel() {
      let ids = table.selected.map((e) => e.id);
      deleteAppReq([...ids]);
    },
    switchApp(r) {
      const appData = computed(() => userStore.getLoginApp?.accessableList || []);
      userStore.setLoginApp({
        currentId: r.clientId,
        clientManagerId: appData.value.filter(e => e.clientId == r.clientId)[0]?.clientManagerIds || [],
        accessableList: unref(appData),
      });
      userStore.loginEnd(true, true);
      tabStore.resetState();
    },
  };

  const pg = reactive({
    current: 1,
    size: 20,
    total: 0,
  });

  const pgActions = {
    resetPg: () => {
      pg.current = 1;
      pg.size = 20;
      pg.total = 0;
    },
    currentChange(r) {
      pg.current = r;
      searchFormActions.onSearch();
    },
    sizeChange(r) {
      pg.current = 1;
      pg.size = r;
      searchFormActions.onSearch();
    },
  };

  const modal = reactive({
    visible: false,
    data: undefined,
  });

  const modalActions = {
    success(p) {
      if (p) {
        // 新建|编辑成功
        let accessableList: any[] = [];
        if (p.type == 'update') {
          accessableList = userStore.getLoginApp.accessableList.map((e) => {
            if (e.clientId == p.id) {
              e.clientName = p.clientName;
              e.autoFlag = p.autoFlag;
            }
            return e;
          });
        } else {
          accessableList = userStore.getLoginApp.accessableList.concat([
            { autoFlag: 0, clientId: p.id, clientName: p.clientName },
          ]);
        }
        userStore.setLoginApp({
          currentId: userStore.getLoginApp.currentId ?? p.id,
          clientManagerId: userStore.getLoginApp.clientManagerId,
          accessableList: accessableList,
        });
      }
      pg.current = 1;
      searchFormActions.onSearch();
    },
    show() {
      modal.visible = true;
    },
  };

  const d_modal = reactive({
    visible: false,
    data: undefined as any,
  });

  // req
  async function deleteAppReq(p) {
    state.loading = true;
    const { respCode, respMsg } = await deleteApp({ ids: p });
    state.loading = false;
    if (respCode != 200) {
      createMessage({
        message: respMsg,
        type: 'warning',
      });
      return;
    }
    userStore.logout(true);
  }

  // modal operations
  function copyAction(data) {
    try {
      let text = `          应用ID:${data.clientId}\n\r
          应用名:${data.clientName}\n\r
          授权范围:${data.scope}\n\r
          授权模式:${data.authorizedGrantTypes}\n\r
          回调地址:${data.webServerRedirectUri}\n\r
          令牌时效:${data.accessTokenValidity}s\n\r
          刷新时效:${data.refreshTokenValidity}s\n\r
          密钥:${data.clientSecretStr}`;
      let input = document.createElement('textarea');
      input.value = text;
      document.body.appendChild(input);
      input.select();
      document.execCommand('copy');
      document.body.removeChild(input);
      createMessage({
        message: '复制成功',
      });
    } catch (err) {
      console.error(err);
    }
  }

  searchFormActions.onSearch();
</script>

<template>
  <div class="p-4 user-management">
    <div class="searchBox px-4 pt-4">
      <el-form inline ref="searchFormRef" :model="searchForm" label-width="60px">
        <el-form-item label="应用名" prop="appName" class="mb-4">
          <el-input v-model="searchForm.appName" placeholder="请输入应用名" clearable />
        </el-form-item>
        <el-form-item label="创建人" prop="createBy" class="mb-4">
          <el-input v-model="searchForm.createBy" placeholder="请输入创建人" clearable />
        </el-form-item>
        <el-form-item label="" class="mb-4">
          <el-button type="primary" :loading="state.loading" @click="searchFormActions.search"
            >查询</el-button
          >
          <el-button @click="searchFormActions.resetFields(searchFormRef)">重置</el-button>
        </el-form-item>
      </el-form>
    </div>
    <div class="middle-content p-4">
      <div class="tools mb-4">
        <div class="toolBtns">
          <el-button type="primary" v-auth="btnPerEnums.CLIENT_ADD" @click="tableActions.create">
            <PlusOutlined />新建
          </el-button>
          <el-popconfirm
            title="确定要删除吗？删除后将退出系统，需要重新登录"
            @confirm="tableActions.batchDel"
            confirm-button-text="确定"
            cancel-button-text="取消"
          >
            <template #reference>
              <el-button
                link
                v-auth="btnPerEnums.CLIENT_DELETE"
                :disabled="table.selected.length == 0"
              >
                <Icon icon="ep:delete" />批量删除
              </el-button>
            </template>
          </el-popconfirm>
        </div>
        <div class="selected">
          已选择<span class="blue">{{ table.selected.length }} 项</span>
        </div>
      </div>
      <el-table
        class="mb-4"
        v-loading="state.loading"
        :data="table.data"
        @selection-change="tableActions.selectionChange"
        :header-cell-style="{ background: '#f1f3f7' }"
      >
        <el-table-column type="selection" width="55" fixed />
        <el-table-column prop="clientId" label="应用ID" :width="120" fixed show-overflow-tooltip />
        <el-table-column prop="clientName" label="应用名" :width="220" show-overflow-tooltip />
        <el-table-column prop="scope" label="授权范围" :width="90" show-overflow-tooltip />
        <el-table-column
          prop="authorizedGrantTypes"
          label="授权模式"
          :width="200"
          show-overflow-tooltip
        >
          <template #default="scope">
            <span>{{
              AUTH_TYPE_LIST.filter((e) =>
                scope.row.authorizedGrantTypes.split(',').includes(e.value),
              )
                .map((e) => e.label)
                .join(',')
            }}</span>
          </template>
        </el-table-column>
        <el-table-column
          prop="webServerRedirectUri"
          label="回调地址"
          :width="250"
          show-overflow-tooltip
        />
        <el-table-column prop="accessTokenValidity" label="令牌时效" :width="200" />
        <el-table-column prop="refreshTokenValidity" label="刷新时效" :width="200" />
        <el-table-column prop="autoFlag" label="组织类型" :width="120">
          <template #default="scope">
            {{ SYNC_SF_TYPE.filter((e) => e.value == scope.row.autoFlag)[0].label }}
          </template>
        </el-table-column>
        <el-table-column prop="remark" label="备注" :width="220" />
        <el-table-column prop="operation" label="操作" :width="220" fixed="right">
          <template #default="scope">
            <el-button link type="primary" @click="tableActions.details(scope.row)">详情</el-button>
            <el-button
              link
              type="primary"
              v-auth="btnPerEnums.CLIENT_EDIT"
              @click="tableActions.update(scope.row)"
              >编辑
            </el-button>
            <el-popconfirm
              title="确定要删除吗？删除后将退出系统，需要重新登录"
              @confirm="tableActions.delete(scope.row)"
              confirm-button-text="确定"
              cancel-button-text="取消"
            >
              <template #reference>
                <el-button link type="danger" v-auth="btnPerEnums.CLIENT_DELETE">删除</el-button>
              </template>
            </el-popconfirm>
            <el-button
              link
              type="primary"
              @click="tableActions.switchApp(scope.row)"
              v-if="currentId != scope.row.clientId"
              >切换</el-button
            >
          </template>
        </el-table-column>
      </el-table>
      <el-pagination
        class="flex justify-end"
        background
        layout="total, sizes, prev, pager, next"
        :total="pg.total"
        :current-page="pg.current"
        v-model:page-size="pg.size"
        @size-change="pgActions.sizeChange"
        @current-change="pgActions.currentChange"
        :page-sizes="[20, 30, 50]"
      />
    </div>
    <AppModal v-model:visible="modal.visible" :data="modal.data" @success="modalActions.success" />

    <el-dialog title="详情" v-model="d_modal.visible" v-if="d_modal.data">
      <el-row :gutter="20" class="mb-2">
        <el-col :span="4" style="text-align: right">clientId:</el-col>
        <el-col :span="20">{{ d_modal.data.clientId }}</el-col>
      </el-row>
      <el-row :gutter="20" class="mb-2">
        <el-col :span="4" style="text-align: right">应用名:</el-col>
        <el-col :span="20">{{ d_modal.data.clientName }}</el-col>
      </el-row>
      <el-row :gutter="20" class="mb-2">
        <el-col :span="4" style="text-align: right">授权范围:</el-col>
        <el-col :span="20">{{ d_modal.data.scope }}</el-col>
      </el-row>
      <el-row :gutter="20" class="mb-2">
        <el-col :span="4" style="text-align: right">授权模式:</el-col>
        <el-col :span="20">{{ d_modal.data.authorizedGrantTypes }}</el-col>
      </el-row>
      <el-row :gutter="20" class="mb-2">
        <el-col :span="4" style="text-align: right">回调地址:</el-col>
        <el-col :span="20">{{ d_modal.data.webServerRedirectUri }}</el-col>
      </el-row>
      <el-row :gutter="20" class="mb-2">
        <el-col :span="4" style="text-align: right">令牌时效:</el-col>
        <el-col :span="20">{{ d_modal.data.accessTokenValidity }}s</el-col>
      </el-row>
      <el-row :gutter="20" class="mb-2">
        <el-col :span="4" style="text-align: right">刷新时效:</el-col>
        <el-col :span="20">{{ d_modal.data.refreshTokenValidity }}s</el-col>
      </el-row>
      <el-row :gutter="20" class="mb-2">
        <el-col :span="4" style="text-align: right">密钥:</el-col>
        <el-col :span="20"
          >{{ d_modal.data.clientSecretStr }}
          <a style="margin-left: 20px" @click="copyAction(d_modal.data)">复制</a>
        </el-col>
      </el-row>
    </el-dialog>
  </div>
</template>

<style lang="less" scoped>
  html[data-theme='light'] {
    .searchBox,
    .middle-content {
      background-color: #fff;
    }
  }

  html[data-theme='dark'] {
    .searchBox,
    .middle-content {
      background-color: #151515;
    }
  }

  .user-management {
    min-height: 100%;
    display: flex;
    flex-direction: column;

    .middle-content {
      flex: 1;

      .tools {
        display: flex;
        justify-content: space-between;
        .selected {
          line-height: 32px;
          .blue {
            margin-left: 5px;
            color: #237ae4;
          }
        }
      }
    }
  }
</style>
